<?php

namespace think\jwt;

use Lcobucci\JWT\Signer;
use Lcobucci\JWT\Signer\Key;
use Lcobucci\JWT\Signer\Rsa;
use Lcobucci\JWT\Signer\Hmac;
use think\jwt\interfaces\EventHandler;
use Lcobucci\JWT\Signer\Hmac\Sha256;
use Lcobucci\JWT\Signer\Key\InMemory;
use think\jwt\exception\InvalidArgumentException;
use Lcobucci\JWT\Signer\Key\LocalFileReference;

class Config
{
    /**
     * Hmac KEY
     * @var string|null
     */
    protected ?string $signer_key = null;

    /**
     * 生成后 一定时间内不能使用
     * @var int
     */
    protected int $not_before = 0;

    /**
     * Token 有效期
     * @var int
     */
    protected int $expires_at = 3600;

    /**
     * Token 可刷新时长
     * @var int
     */
    protected int $refresh_ttL = 7200;

    /**
     * Token 加密类型
     * @var string
     */
    protected string $signer = Sha256::class;

    /**
     * Token 获取途径
     * @var string
     */
    protected string $type = 'Header';

    /**
     * Token 签发者
     * @var string
     */
    protected string $iss = 'client.think.cn';

    /**
     * Token 接收方
     * @var string
     */
    protected string $aud = 'server.think.cn';

    /**
     * Token 是否自动续签
     * @var bool
     */
    protected bool $automatic_renewal = false;

    /**
     * Token 用户模型
     * @var string|null
     */
    protected string|null $user_model;

    /**
     * RSA 加密下公钥地址
     * @var string
     */
    protected string $public_key = '';

    /**
     * RSA 加密下私钥地址
     * @var string
     */
    protected string $private_key = '';

    /**
     * 事件回调
     * @var EventHandler|string|null
     */
    protected EventHandler|string|null $event_handler;
    private int $relogin_code;
    private int $refresh_code;

    public function __construct(array $options)
    {
        foreach ($options as $key => $value) {
            $this->$key = $value;
        }
    }

    /**
     * 获取 加密密钥
     *
     * @return InMemory
     */
    public function getHmacKey(): Key
    {
        if (empty($this->signer_key)) {
            throw new InvalidArgumentException('config signer_key required.', 500);
        }

        return InMemory::base64Encoded((string)$this->signer_key);
    }

    /**
     * 获取 是否使用 RSA 加密
     *
     * @return bool
     */
    public function RSASigner(): bool
    {
        $signer = $this->getSigner();

        return $signer instanceof Rsa;
    }

    /**
     * 获取 加密key
     *
     * @return Key
     */
    public function getSignerKey(): Key
    {
        $signer = $this->getSigner();

        if ($this->RSASigner()) {
            return $this->getPrivateKey();
        } else if ($signer instanceof Hmac) {
            return $this->getHmacKey();
        } else {
            throw new InvalidArgumentException('not support.', 500);
        }
    }

    /**
     * 获取 RSA 公钥
     *
     * @return Key
     */
    public function getPublicKey(): Key
    {
        return LocalFileReference::file($this->public_key);
    }

    /**
     * 获取 RSA 私钥
     *
     * @return Key
     */
    public function getPrivateKey(): Key
    {
        return LocalFileReference::file($this->private_key);
    }

    /**
     * 获取有效果期
     *
     * @return int
     */
    public function getExpires(): int
    {
        return $this->expires_at;
    }

    public function setExpires(int $ttl)
    {
        $this->expires_at = $ttl;
    }

    /**
     * 获取刷新ttl
     *
     * @return int|string
     */
    public function getRefreshTTL(): int|string
    {
        return $this->refresh_ttL;
    }

    /**
     * 获取iss
     *
     * @return string
     */
    public function getIss(): string
    {
        return $this->iss;
    }

    /**
     * 获取auid
     *
     * @return string
     */
    public function getAud(): string
    {
        return $this->aud;
    }

    /**
     * 获取not_before
     *
     * @return int
     */
    public function getNotBefore(): int
    {
        return $this->not_before;
    }

    /**
     * 获取加密对象
     *
     * @return Signer
     */
    public function getSigner(): Signer
    {
        return new $this->signer;
    }


    /**
     * 获取重新登录code
     *
     * @return int
     */
    public function getReloginCode(): int
    {
        return $this->relogin_code;
    }

    /**
     * 获取刷新code
     *
     * @return int
     */
    public function getRefreshCode(): int
    {
        return $this->refresh_code;
    }

    /**
     * 获取是否自动续签
     *
     * @return bool
     */
    public function getAutomaticRenewal(): bool
    {
        return $this->automatic_renewal;
    }

    /**
     * 获取token途径
     *
     * @return string|null
     */
    public function getType(): ?string
    {
        return $this->type;
    }

    /**
     * 获取事件
     *
     * @return EventHandler|string|null
     */
    public function getEventHandler(): EventHandler|string|null
    {
        return $this->event_handler ?: null;
    }

    /**
     * 获取用户模型
     *
     * @return string|null
     */
    public function getUserModel(): ?string
    {
        return $this->user_model;
    }
}